<script setup>
import { ref, inject, computed, onMounted, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { useAuthStore } from '@/stores/auth'
import { useConfigStore } from '@/stores/config'
import userApi from '@/apis/user'

import SendCaptcha from '@/components/user/SendCaptcha.vue'
import ImgCaptcha from '@/components/form/imgCaptcha.vue'

const agreement = inject('showAgreement')

const route = useRoute()
const router = useRouter()

const authStore = useAuthStore()
const configStore = useConfigStore()

//是否允许短信登录
const allowMobileLogin = computed(() =>
  configStore.get('user.mobile_feature', []).includes('login')
)

const loginTypes = computed(() => {
  let result = ['password']
  if (allowMobileLogin.value) result.push('sms')
  return result
})

const activeTab = ref(route.query?.type ?? 'password')
if (!activeTab.value.includes(activeTab)) activeTab.value = loginTypes.value[0] ?? ''

const form = ref(null)
const rules = ref({
  captcha: [
    { required: true, message: '请输入验证码', trigger: 'blur' },
    {
      validator: (rule, value, callback) => {
        if (value.length < 4 || value.length > 6) {
          callback(new Error('验证码格式错误'))
        } else {
          callback()
        }
      },
    },
  ],
  agreement: [{ required: true, message: '请先阅读并同意协议内容', trigger: 'change' }],
})
const model = ref({
  captcha: '',
  agreement: [],
  invite: '',
})
const imgCaptchaRef = ref(null)

watch(activeTab, (val) => {
  model.value.captcha = ''
  if (val === 'password') {
    model.value.username = ''
    model.value.password = ''
    rules.value.username = [{ required: true, message: '请输入账号', trigger: 'blur' }]
    rules.value.password = [{ required: true, message: '请输入密码', trigger: 'blur' }]
    delete model.value.mobile
    delete rules.value.mobile
  } else if ((val = 'sms')) {
    model.value.mobile = ''
    rules.value.mobile = [
      { required: true, message: '请输入手机号', trigger: 'blur' },
      {
        validator: (rule, value, callback) => {
          if (!/^1[3456789]\d{9}$/.test(value)) {
            callback(new Error('手机号格式错误'))
          } else {
            callback()
          }
        },
      },
    ]
    delete model.value.username, model.value.password
    delete rules.value.username, rules.value.password
  }
})

const submitForm = async () => {
  const values = model.value
  values.type = activeTab.value
  await form.value.validate(async (valid) => {
    if (valid) {
      try {
        const { data } = await userApi.passport.login(values)
        authStore.setAuth(data)
        ElMessage.success('登录成功')
        //获取路由上的redirect参数
        const path = decodeURIComponent(route.query?.redirect || '/user')
        //跳转到登录成功页面
        await router.replace(path)
      } catch (error) {
        //更新验证码
        if (imgCaptchaRef.value) {
          imgCaptchaRef.value.getCaptcha()
        }
        return false
      }
    } else {
      return false
    }
  })
}

onMounted(() => {
  //因为短信登录可直接注册，所以可以设置邀请码
  const code = sessionStorage.getItem('inviteCode') || ''
  if (code.length > 0) model.value.invite = code
})
</script>

<template>
  <div class="text-center font-bold text-2xl">用户登录</div>
  <div class="login-type flex-1 mt-5 space-y-5" v-if="loginTypes.length > 0">
    <el-segmented
      v-if="loginTypes.length > 1"
      v-model="activeTab"
      :options="[
        { label: '密码登录', value: 'password' },
        { label: '短信登录', value: 'sms' },
      ]"
    />
    <el-form ref="form" :model="model" label-width="auto" :rules="rules">
      <el-form-item label="账号" prop="username" v-if="activeTab === 'password'">
        <el-input v-model="model.username" placeholder="请输入账号" />
      </el-form-item>
      <el-form-item label="密码" prop="password" v-if="activeTab === 'password'">
        <el-input type="password" v-model="model.password" placeholder="请输入密码" />
      </el-form-item>
      <el-form-item label="验证码" prop="captcha" v-if="activeTab === 'password'">
        <el-input v-model="model.captcha" placeholder="请输入验证码">
          <template #suffix><ImgCaptcha ref="imgCaptchaRef" class="h-7" /></template>
        </el-input>
      </el-form-item>
      <el-form-item label="手机号" prop="mobile" v-if="activeTab === 'sms'">
        <el-input v-model="model.mobile" placeholder="请输入手机号"> </el-input>
      </el-form-item>
      <el-form-item label="验证码" prop="captcha" v-if="activeTab === 'sms'">
        <el-input v-model="model.captcha" placeholder="请输入短信验证码">
          <template #append>
            <SendCaptcha type="mobile" :account="model.mobile" event="login" />
          </template>
        </el-input>
      </el-form-item>
      <el-form-item label="&nbsp;" prop="agreement">
        <el-checkbox-group v-model="model.agreement">
          <div class="flex justify-between items-center">
            <el-checkbox value="1" name="agreement">
              <span class="text-[--el-text-color-secondary] text-xs font-normal">
                我已经阅读并同意<span class="agreement-link" @click="agreement('agreement')"
                  >用户协议</span
                >和<span class="agreement-link" @click="agreement('privacy')">隐私政策</span>
              </span>
            </el-checkbox>
          </div>
        </el-checkbox-group>
      </el-form-item>
      <el-form-item label=" ">
        <el-button type="primary" @click="submitForm()">
          <FontAwesomeIcon icon="sign-in-alt" />
          <span class="pl-1">登录</span>
        </el-button>
      </el-form-item>
    </el-form>
  </div>
  <div v-else class="py-10 text-center text-[--el-text-color-primary]">
    <p class="mb-10 text-[--el-color-warning]">
      <FontAwesomeIcon icon="info-circle" size="4x" />
    </p>
    <p>抱歉，登录功能已关闭。</p>
  </div>
</template>

<style scoped>
.login-type .el-segmented {
  --el-segmented-item-selected-color: var(--el-text-color-primary);
  --el-segmented-item-selected-bg-color: var(--el-fill-color-darker);
  width: 100%;
  height: 2rem;
}

.login-tab-item {
  @apply flex-1 rounded py-1 px-4 text-center transition text-[--el-text-color-secondary] cursor-pointer;
}

.login-tab-item.active {
  @apply bg-[--el-color-primary-light-8] text-[--el-color-primary];
}

.login-tab-slider {
  @apply absolute top-0.5 bottom-0.5 rounded bg-[--el-color-primary-light-8] transition-all duration-200 ease-in-out -z-10;
}

.agreement-link {
  @apply text-[--el-color-primary] cursor-pointer px-0.5;
}
</style>
